home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume1 / xref < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  9.2 KB

  1. Date: Fri, 24 May 85 13:32:11 cdt
  2. From: harvard!seismo!uwvax!uwmacc!jiml (Jim Leinweber)
  3. Subject: a cross reference program
  4. Organization: U Wisconsin-Madison Academic Computing Ctr
  5.  
  6. In the last few months a couple of requests for f77 or C cross
  7. reference map generators have appeared on the net.  This submission
  8. is a quick and dirty implementation of a general purpose (i.e. stupid)
  9. cross reference utility.  It was done using lex, awk, and sh as an
  10. example for a UNIX tutorial.  I have mailed copies to the original
  11. requestors.  Possibly some of the rest of the net isn't satisfied by
  12. egrep, ctags, ptx, etc., and might like it too.
  13.  
  14. -- Jim Leinweber  (jiml@uwmacc.UUCP, leinwebe@wisc-ai.arpa)
  15.  
  16. ----------------- cut here --------------------
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line,
  19. # then unpack it by saving it in a file and typing "sh file".
  20. #
  21. # Wrapped by uwmacc!jiml on Fri May 24 12:42:06 CDT 1985
  22. # Contents:  Makefile READ_ME mergelines.awk xref.man xref.man.sh xref.sh
  23. #    xrefhead.sh xreflex.l
  24.  
  25. echo x - Makefile
  26. sed 's/^x//' > "Makefile" <<'x//E*O*F Makefile//'
  27. xCFLAGS = -O
  28. xLINT = lint -ph
  29. xDESTDIR = /usr/local
  30. xMANLOC = /usr/man/manl/xref.l
  31. x
  32. xall : xref xreflex xref.1 ; @echo 1>&2 "[Made xref xreflex xref.1]"
  33. x
  34. xxref : xrefhead.sh mergelines.awk ; sh xref.sh $(DESTDIR) >/dev/null
  35. x
  36. xxreflex : lex.yy.c ; cc -o xreflex $(CFLAGS) lex.yy.c -ll
  37. xlex.yy.c : xreflex.l ; lex -v xreflex.l
  38. x
  39. xxref.1 : xref.man ; sh xref.man.sh $(DESTDIR) >/dev/null
  40. x
  41. x
  42. xpiecetest :
  43. x    xreflex xreflex.l xref.man >xreflex_out
  44. x    sort -u +0f -1 +0 -1 +1 -2 +2n <xreflex_out >sort_out
  45. x    awk -f mergelines.awk <sort_out >awk_out
  46. x
  47. xlint : lex.yy.c ; $(LINT) lex.yy.c > xreflex.lint
  48. x
  49. xinstall : all
  50. x    install -c xref $(DESTDIR)
  51. x    install -c -s xreflex $(DESTDIR)
  52. x    install -c -m 644 xref.1 $(MANLOC)
  53. x
  54. xclean : ; -rm *_out *.lint *.yy.c xref xreflex xref.1
  55. x//E*O*F Makefile//
  56. chmod  u=rw,g=r,o=r  Makefile
  57.  
  58. echo x - READ_ME
  59. sed 's/^x//' > "READ_ME" <<'x//E*O*F READ_ME//'
  60. xIn the last few months there have been requests on USENET for a cross
  61. xreferencing program.  Standard UNIX usage is, one supposes, to use
  62. xegrep on a case by case basis for this purpose.  However, I cobbled up
  63. xsuch a program as an example using of using make, lex and awk for a
  64. xshort UNIX tutorial.  It has had only minimal testing and is not
  65. xespecially efficient;  caveat emptor!
  66. x
  67. xThis package makes three files:
  68. x    xref - a shell script which cross references files
  69. x    xreflex - a lex(1) program used by xref
  70. x    xref.1 - a manual entry for xref
  71. x
  72. xIt was developed on a 4.2BSD system, and assumes that make, lex, cc, 
  73. xsh, ed, fgrep, sort, and awk are available under /bin or
  74. x/usr/{bin,ucb,local}.  It should run with at worst minimal changes
  75. xunder any other flavor of UNIX.  If fgrep, sort, and awk are somewhere
  76. xelse be sure to change the PATH in xrefhead.sh.
  77. x
  78. xThe idea is to cross reference files by "xref file1 ... >listing".
  79. xA pipeline of the form "lex program | fgrep | sort | awk" extracts
  80. xwords and their locations, discards extraneous ones, sorts the rest,
  81. xand merges the resulting name,file,line triples into a fairly standard
  82. xcross reference map.
  83. x
  84. xVarious make targets are available:
  85. x    make all        # makes xref & xreflex for /usr/local
  86. x    make DESTDIR=somewhere all    # ... for somewhere instead.
  87. x    make piecetest    # produce intermediate *_out files.
  88. x    make DESTDIR=somewhere MANLOC=elsewhere install
  89. x            # install xref, xreflex, xref.1
  90. x    make clean        # remove computed files
  91. x
  92. xxref is produced by minor editing from xrefhead.sh and mergelines.awk.
  93. xxref.1 is produced by minor editing from xref.man.
  94. xxreflex is produced by lex and cc from xref.l.
  95. x
  96. x-- Jim Leinweber  (jiml@uwmacc.UUCP, leinwebe@wisc-ai.ARPA)
  97. xMadison Academic Computing Center, 1210 W. Dayton ST., Madison Wi 53706
  98. x//E*O*F READ_ME//
  99. chmod  u=rw,g=r,o=r  READ_ME
  100.  
  101. echo x - mergelines.awk
  102. sed 's/^x//' > "mergelines.awk" <<'x//E*O*F mergelines.awk//'
  103. x# Input: lines of the form "name \t file \t line number"
  104. x# Output: merged lines of the form "name \t file \t n1 n2 n3 ..."
  105. x#   Starts a new line for new names or files, and when line gets long.
  106. x#   Suppresses name and previous file on continuation lines.
  107. x
  108. xBEGIN { # Print header and compute usable width
  109. x    fmt = "%-14s\t%-14s\t%s\n"
  110. x    printf fmt, "NAME", "FILE", "LINE NUMBERS"
  111. x    ###uwidth = '$width'-16-16-5;  # sizes of name, file, number
  112. x    if (uwidth<3) uwidth=80-16-16-5;  }
  113. x
  114. x$1 != name { printf fmt, pname, pfile, line;  
  115. x    name = pname = $1;  file = pfile = $2;  line = "" }
  116. x
  117. x$2 != file { printf fmt, pname, pfile, line;  
  118. x    pname = "";  file = pfile = $2;  line = "" }
  119. x
  120. xlength(line) > uwidth { printf fmt, pname, pfile, line;  
  121. x    pname = "";  pfile = "";  line = "" }
  122. x
  123. x{ line = line " " sprintf("%4s",$3) }
  124. x
  125. xEND { printf fmt, pname, pfile, line }
  126. x//E*O*F mergelines.awk//
  127. chmod  u=rw,g=r,o=r  mergelines.awk
  128.  
  129. echo x - xref.man
  130. sed 's/^x//' > "xref.man" <<'x//E*O*F xref.man//'
  131. x.TH XREF LOCAL U-WISC
  132. x.ad b
  133. x.SH NAME
  134. xxref \- cross reference files
  135. x.SH SYNOPSIS
  136. x\fBxref\fR [\fB-k\fR keyfile] [\fB-w\fR n] file ...
  137. x.SH DESCRIPTION
  138. x.I Xref
  139. xcross references to standard output
  140. xall the "names" in its (text) input files
  141. xtogether with the files and line numbers they occur on.
  142. xIf no files are supplied, it reads standard input.
  143. xNames consist of letters, underscores, and (non-initial) digits.
  144. x.PP
  145. xAvailable options are:
  146. x.TP
  147. x.B \-k " keyfile"
  148. xUse keyfile as a list of words which should be
  149. xsuppressed from the cross reference.
  150. xAs the removal is done via "fgrep -v", the words should occur one
  151. xper line.
  152. xTo prevent internal matches from discarding valid longer words,
  153. xeach word can be preceded by a space and followed by a tab.
  154. xBy default all words are included.
  155. x.TP
  156. x.B \-w " n"
  157. xFormat the output with a width of n columns, by default 80.
  158. xN is primarily intended for raising the line length;
  159. xa lower limit of 40 is silently enforced.
  160. x.ne 5
  161. x.SH FILES
  162. x.br
  163. x???usrlocal/xreflex    first stage of xref (lexical analyzer)
  164. x.SH DIAGNOSTICS
  165. xComplains about unreadable files, and exits with status 2 if no
  166. xfiles can be read.
  167. xUnhappy subprocesses (fgrep, sort, awk) may also bleat.
  168. x.SH "SEE ALSO"
  169. xctags(1),
  170. xegrep(1),
  171. xptx(1)
  172. x.SH BUGS
  173. xFilenames containing shell meta-characters may be misprocessed.
  174. xThe four stage pipeline is relatively inefficient.
  175. xA general purpose program cannot take advantage of semantic
  176. xknowledge of its input in order to produce prettier, better classified
  177. xoutput.
  178. x.SH AUTHOR
  179. xJim Leinweber
  180. x//E*O*F xref.man//
  181. chmod  u=rw,g=r,o=r  xref.man
  182.  
  183. echo x - xref.man.sh
  184. sed 's/^x//' > "xref.man.sh" <<'x//E*O*F xref.man.sh//'
  185. x>xref.1
  186. xed xref.1 <<EOF
  187. xr xref.man
  188. x/???usrlocal/p
  189. xs;;$1;p
  190. xw
  191. xq
  192. xEOF
  193. x//E*O*F xref.man.sh//
  194. chmod  u=rw,g=r,o=r  xref.man.sh
  195.  
  196. echo x - xref.sh
  197. sed 's/^x//' > "xref.sh" <<'x//E*O*F xref.sh//'
  198. x>xref
  199. xed xref <<EOF
  200. xr xrefhead.sh
  201. x/???usrlocal/p
  202. xs;;$1;p
  203. x\$r mergelines.awk
  204. xg/###/s///p
  205. x\$s/.*/&'/p
  206. xw
  207. xq
  208. xEOF
  209. x//E*O*F xref.sh//
  210. chmod  u=rw,g=r,o=r  xref.sh
  211.  
  212. echo x - xrefhead.sh
  213. sed 's/^x//' > "xrefhead.sh" <<'x//E*O*F xrefhead.sh//'
  214. x#! /bin/sh
  215. x# quick and dirty cross reference generator
  216. x
  217. xDESTDIR=???usrlocal            # revised by Makefile
  218. xPATH=/bin:/usr/bin:/usr/ucb:$DESTDIR    # revise these if necessary
  219. x
  220. xwidth=80                # defaults
  221. xfarg="-e '~'"                # a dummy character
  222. x
  223. xfiles=""
  224. xwhile true
  225. xdo
  226. x    case "$1" in
  227. x    "")    break;;
  228. x    -k)    keywords=$2; shift
  229. x        farg="-f $keywords";;
  230. x    -w)    width=$2; shift;;
  231. x    -*)    echo 1>&2 "Usage:  xref [-k keyfile] [-w n] [file ...]"
  232. x        exit 2;;
  233. x     *)    files="$files $1";;
  234. x    esac
  235. x    shift
  236. xdone
  237. x
  238. xxreflex $files |
  239. x    fgrep -v $farg |
  240. x    sort -u +0f -1 +0 -1 +1 -2 +2n |
  241. x        awk '\
  242. x//E*O*F xrefhead.sh//
  243. chmod  u=rw,g=r,o=r  xrefhead.sh
  244.  
  245. echo x - xreflex.l
  246. sed 's/^x//' > "xreflex.l" <<'x//E*O*F xreflex.l//'
  247. x%{
  248. x#define INFINITE_LOOP  while (1)
  249. xint gargc;        /* global argc duplicate */
  250. xchar **gargv;        /* global argv duplicate */
  251. xint n = 1;        /* line counter */
  252. xchar *fname = "-";    /* current file name */
  253. x
  254. x%}
  255. xstartid [A-Za-z_]
  256. xmoreid [A-Za-z_0-9]
  257. x%%
  258. x{startid}{moreid}*    printf(" %s\t%s\t%d\n", yytext, fname, n);
  259. x\n            n++;
  260. x.            ;
  261. x%%
  262. x
  263. xyywrap()
  264. x{
  265. x    /* reset line count & proceed to next file, or quit */
  266. x    n = 1;
  267. x    if (next_open())   return(0);
  268. x    else   exit(0);
  269. x}
  270. x
  271. xnext_open()
  272. x{
  273. x    (void) fclose(stdin);
  274. x    while (--gargc > 0) {
  275. x    fname = *++gargv;
  276. x    if (fopen(fname,"r") != NULL)
  277. x        return(1);
  278. x    fprintf(stderr, "xref: can't open %s\n", fname);
  279. x    }
  280. x    return(0);
  281. x}
  282. x
  283. xmain(argc,argv,env)
  284. xint argc;   char **argv;   char *env[];
  285. x{
  286. x    gargc = argc;   gargv=argv;
  287. x    if (gargc==1 || next_open())
  288. x    INFINITE_LOOP (void) yylex();
  289. x    exit(2);
  290. x}
  291. x//E*O*F xreflex.l//
  292. chmod  u=rw,g=r,o=r  xreflex.l
  293.  
  294. echo Inspecting for damage in transit...
  295. temp=/tmp/shar$$   dtemp=/tmp/.shar$$
  296. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  297. cat > $temp <<\!!!
  298.       28     117     746 Makefile
  299.       38     289    1792 READ_ME
  300.       23     161     847 mergelines.awk
  301.       49     251    1509 xref.man
  302.        8      11      66 xref.man.sh
  303.       11      15     108 xref.sh
  304.       28      84     557 xrefhead.sh
  305.       44     123     837 xreflex.l
  306.      229    1051    6462 total
  307. !!!
  308. wc  Makefile READ_ME mergelines.awk xref.man xref.man.sh xref.sh\
  309. xrefhead.sh xreflex.l | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  310. if [ -s $dtemp ]
  311. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  312. else echo "No problems found."
  313. fi
  314. exit 0
  315.  
  316.